#ifndef __SUBSYSTEM_INVENTORIES_H__
#define __SUBSYSTEM_INVENTORIES_H__

#include <vector>
#include <unordered_map>
#include <mutex>

#include "Game/IInventory.hpp"

#include "Subsystem.hpp"
#include "GameStack.hpp"
#include "GameEnum.h"

namespace PocketSurvival
{
    class SubsystemInventories : public Subsystem
    {
    public:
        uint32_t registerInventory(IInventory *inventory);
        IInventory *getInventory(uint32_t id);
        bool removeInventoryById(uint32_t id);
        inline bool removeInventory(IInventory *inventory);
        
        bool handleMoveItem(uint32_t sourceId, uint32_t sourceSlotIndex, uint32_t targetId, uint32_t targetSlotIndex, uint32_t count);
        bool handleDragDrop(uint32_t sourceId, uint32_t sourceSlotIndex, DragMode dragMode, uint32_t targetId, uint32_t targetSlotIndex, bool processingOnly);

        void pushSyncItem(IInventory *inventory, int32_t slotIndex);

    public:
        SubsystemInventories() noexcept;

        virtual void onEntityAdded(entt::entity entity) override;
        virtual void onEntityRemoved(entt::entity entity) override;

        virtual void load(const nlohmann::json& jsonData) override;
        virtual void save(nlohmann::json& jsonData) override;
        virtual void saveToMsgJson(nlohmann::json &jsonData) override;

        virtual const std::string& getName() const override;

    protected:
        std::unordered_map<uint32_t, IInventory *> m_inventoryMap;
        uint32_t m_endID = 0;
        GameStack<uint32_t> m_idStack;
        std::mutex m_mutex;
    };

    inline SubsystemInventories::SubsystemInventories() noexcept 
    {
        m_inventoryMap.clear();
    }

    inline bool SubsystemInventories::removeInventory(IInventory *inventory)
    {
        return removeInventoryById(inventory->id);
    }
}

#endif